home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 023 / ver30 / region.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  5KB  |  219 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Region based commands.
  4.  * Version:    29
  5.  * Last edit:    12-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  * What:    Region operations.
  9.  *
  10.  * The routines in this file
  11.  * deal with the region, that magic space
  12.  * between "." and mark. Some functions are
  13.  * commands. Some functions are just for
  14.  * internal use.
  15.  */
  16. #include    "def.h"
  17.  
  18. /*
  19.  * Kill the region. Ask "getregion"
  20.  * to figure out the bounds of the region.
  21.  * Move "." to the start, and kill the characters.
  22.  */
  23. killregion(f, n, k)
  24. {
  25.     register int    s;
  26.     REGION        region;
  27.  
  28.     if ((s=getregion(®ion)) != TRUE)
  29.         return (s);
  30.     if ((lastflag&CFKILL) == 0)        /* This is a kill type    */
  31.         kdelete();            /* command, so do magic    */
  32.     thisflag |= CFKILL;            /* kill buffer stuff.    */
  33.     curwp->w_dotp = region.r_linep;
  34.     curwp->w_doto = region.r_offset;
  35.     return (ldelete(region.r_size, TRUE));
  36. }
  37.  
  38. /*
  39.  * Copy all of the characters in the
  40.  * region to the kill buffer. Don't move dot
  41.  * at all. This is a bit like a kill region followed
  42.  * by a yank.
  43.  */
  44. copyregion(f, n, k)
  45. {
  46.     register LINE    *linep;
  47.     register int    loffs;
  48.     register int    s;
  49.     REGION        region;
  50.  
  51.     if ((s=getregion(®ion)) != TRUE)
  52.         return (s);
  53.     if ((lastflag&CFKILL) == 0)        /* Kill type command.    */
  54.         kdelete();
  55.     thisflag |= CFKILL;
  56.     linep = region.r_linep;            /* Current line.    */
  57.     loffs = region.r_offset;        /* Current offset.    */
  58.     while (region.r_size--) {
  59.         if (loffs == llength(linep)) {    /* End of line.        */
  60.             if ((s=kinsert('\n')) != TRUE)
  61.                 return (s);
  62.             linep = lforw(linep);
  63.             loffs = 0;
  64.         } else {            /* Middle of line.    */
  65.             if ((s=kinsert(lgetc(linep, loffs))) != TRUE)
  66.                 return (s);
  67.             ++loffs;
  68.         }
  69.     }
  70.     return (TRUE);
  71. }
  72.  
  73. /*
  74.  * Lower case region. Zap all of the upper
  75.  * case characters in the region to lower case. Use
  76.  * the region code to set the limits. Scan the buffer,
  77.  * doing the changes. Call "lchange" to ensure that
  78.  * redisplay is done in all buffers. 
  79.  */
  80. lowerregion(f, n, k)
  81. {
  82.     register LINE    *linep;
  83.     register int    loffs;
  84.     register int    c;
  85.     register int    s;
  86.     REGION        region;
  87.  
  88.     if ((s=getregion(®ion)) != TRUE)
  89.         return (s);
  90.     lchange(WFHARD);
  91.     linep = region.r_linep;
  92.     loffs = region.r_offset;
  93.     while (region.r_size--) {
  94.         if (loffs == llength(linep)) {
  95.             linep = lforw(linep);
  96.             loffs = 0;
  97.         } else {
  98.             c = lgetc(linep, loffs);
  99.             if (ISUPPER(c) != FALSE)
  100.                 lputc(linep, loffs, TOLOWER(c));
  101.             ++loffs;
  102.         }
  103.     }
  104.     return (TRUE);
  105. }
  106.  
  107. /*
  108.  * Upper case region. Zap all of the lower
  109.  * case characters in the region to upper case. Use
  110.  * the region code to set the limits. Scan the buffer,
  111.  * doing the changes. Call "lchange" to ensure that
  112.  * redisplay is done in all buffers. 
  113.  */
  114. upperregion(f, n, k)
  115. {
  116.     register LINE    *linep;
  117.     register int    loffs;
  118.     register int    c;
  119.     register int    s;
  120.     REGION        region;
  121.  
  122.     if ((s=getregion(®ion)) != TRUE)
  123.         return (s);
  124.     lchange(WFHARD);
  125.     linep = region.r_linep;
  126.     loffs = region.r_offset;
  127.     while (region.r_size--) {
  128.         if (loffs == llength(linep)) {
  129.             linep = lforw(linep);
  130.             loffs = 0;
  131.         } else {
  132.             c = lgetc(linep, loffs);
  133.             if (ISLOWER(c) != FALSE)
  134.                 lputc(linep, loffs, TOUPPER(c));
  135.             ++loffs;
  136.         }
  137.     }
  138.     return (TRUE);
  139. }
  140.  
  141. /*
  142.  * This routine figures out the bound of the region
  143.  * in the current window, and stores the results into the fields
  144.  * of the REGION structure. Dot and mark are usually close together,
  145.  * but I don't know the order, so I scan outward from dot, in both
  146.  * directions, looking for mark. The size is kept in a long. At the
  147.  * end, after the size is figured out, it is assigned to the size
  148.  * field of the region structure. If this assignment loses any bits,
  149.  * then we print an error. This is "type independent" overflow
  150.  * checking. All of the callers of this routine should be ready to
  151.  * get an ABORT status, because I might add a "if regions is big,
  152.  * ask before clobberring" flag.
  153.  */
  154. getregion(rp)
  155. register REGION    *rp;
  156. {
  157.     register LINE    *flp;
  158.     register LINE    *blp;
  159.     register long    fsize;            /* Long now.        */
  160.     register long    bsize;
  161.  
  162.     if (curwp->w_markp == NULL) {
  163.         eprintf("No mark in this window");
  164.         return (FALSE);
  165.     }
  166.     if (curwp->w_dotp == curwp->w_markp) {    /* "r_size" always ok.    */
  167.         rp->r_linep = curwp->w_dotp;
  168.         if (curwp->w_doto < curwp->w_marko) {
  169.             rp->r_offset = curwp->w_doto;
  170.             rp->r_size = curwp->w_marko-curwp->w_doto;
  171.         } else {
  172.             rp->r_offset = curwp->w_marko;
  173.             rp->r_size = curwp->w_doto-curwp->w_marko;
  174.         }
  175.         return (TRUE);
  176.     }
  177.     blp = curwp->w_dotp;            /* Get region size.    */
  178.     flp = curwp->w_dotp;
  179.     bsize = curwp->w_doto;
  180.     fsize = llength(flp)-curwp->w_doto+1;
  181.     while (flp!=curbp->b_linep || lback(blp)!=curbp->b_linep) {
  182.         if (flp != curbp->b_linep) {
  183.             flp = lforw(flp);
  184.             if (flp == curwp->w_markp) {
  185.                 rp->r_linep = curwp->w_dotp;
  186.                 rp->r_offset = curwp->w_doto;
  187.                 return (setsize(rp, fsize+curwp->w_marko));
  188.             }
  189.             fsize += llength(flp)+1;
  190.         }
  191.         if (lback(blp) != curbp->b_linep) {
  192.             blp = lback(blp);
  193.             bsize += llength(blp)+1;
  194.             if (blp == curwp->w_markp) {
  195.                 rp->r_linep = blp;
  196.                 rp->r_offset = curwp->w_marko;
  197.                 return (setsize(rp, bsize-curwp->w_marko));
  198.             }
  199.         }
  200.     }
  201.     eprintf("Bug: lost mark");        /* Gak!            */
  202.     return (FALSE);
  203. }
  204.  
  205. /*
  206.  * Set size, and check for overflow.
  207.  */
  208. setsize(rp, size)
  209. register REGION    *rp;
  210. register long    size;
  211. {
  212.     rp->r_size = size;
  213.     if (rp->r_size != size) {
  214.         eprintf("Region is too large");
  215.         return (FALSE);
  216.     }
  217.     return (TRUE);
  218. }
  219.